# @Filename:    functools_wraps
# @Author:      王佳伟
# @Time:        2025-02-07 14:01
# @Describe:
import functools
import multiprocessing
import os
import time

'''
装饰器配合多进程，报错！！
这个错误是因为pickle不能序列化local对象。在你的代码中，你使用了装饰器来修改了函数对象，这导致了local对象的产生。当你试图在子进程中执行这些被装饰过的函数时，会出现这个错误。

为了避免这个错误，你可以将被装饰的函数移动到一个单独的模块中，并在需要的时候导入它们。或者你可以使用另一种不会产生local对象的装饰器实现计时功能，例如使用装饰器functools.wraps()来保留函数的元信息。
'''

'''
Python装饰器（decorator）在实现的时候，被装饰后的函数其实已经是另外一个函数了（函数名等函数属性会发生改变），
为了不影响，Python的functools包中提供了一个叫wraps的decorator来消除这样的副作用。
写一个decorator的时候，最好在实现之前加上functools的wrap，它能保留原有函数的名称和函数属性
所以这样写就可以了：
'''

def time_time(func):
    @functools.wraps(func) # 使用functools.wraps()将被装饰的函数的元信息复制到装饰器函数中
    def wrapper(*arg, **key):
        start = time.time()
        result = func(*arg, **key)
        end = time.time()
        print(end - start)
        return result
    return wrapper

@time_time
def work_a():
    for i in range(10):
        print(i, 'a', os.getpid())
        time.sleep(1)

@time_time
def work_b():
    for i in range(10):
        print(i, 'b', os.getpid())
        time.sleep(1)

if __name__ == '__main__':
    work_a()
    work_b()
    a_p = multiprocessing.Process(target=work_a)
    b_p = multiprocessing.Process(target=work_b)

    for p in (a_p, b_p):
        p.start()